package cn.wps.solution.demo.service;

import cn.wps.solution.demo.entity.File;
import cn.wps.solution.demo.entity.FileId;
import cn.wps.solution.demo.repository.FileRepository;
import cn.wps.solution.weboffice.provider.v3.exception.FileNotExist;
import cn.wps.solution.weboffice.provider.v3.exception.FileVersionNotExist;
import cn.wps.solution.weboffice.provider.v3.model.DownloadInfo;
import cn.wps.solution.weboffice.provider.v3.model.FileInfo;
import cn.wps.solution.weboffice.provider.v3.model.Watermark;
import cn.wps.solution.weboffice.provider.v3.service.ExtendCapacityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

@Service
public class ExtendCapacityServiceImpl implements ExtendCapacityService {
    @Value("${weboffice.provider.host:http://localhost:8080}")
    private String host;

    @Autowired
    private PreviewServiceImpl previewService;

    @Autowired
    private FileRepository fileRepository;

    @Override
    public void renameFile(String fileId, String name) {
        Optional.ofNullable(previewService.fetchFile(fileId))
                .ifPresentOrElse(
                        f -> {
                            f.setName(name);
                            fileRepository.save(f);
                        },
                        FileNotExist::new
                );
    }

    @Override
    public List<FileInfo> fileVersions(String fileId, int offset, int limit) {
        // ATTENTION no pagination, returns all versions
        return Optional.ofNullable(fileId)
                .map(fileRepository::findByIdId)
                .map(List::stream)
                .map(s -> StreamSupport.stream(s.spliterator(), false))
                .map(s -> s.map(File::toFileInfo))
                .map(s -> s.collect(Collectors.toList()))
                .orElseThrow(FileNotExist::new);
    }

    File fetchFileVersion(String fileId, int version) {
        return Optional.ofNullable(fileId)
                .map(id -> FileId.builder().id(fileId).version(version).build())
                .flatMap(fileRepository::findById)
                .orElseThrow(FileNotExist::new);
    }

    @Override
    public FileInfo fileVersion(String fileId, int version) {
        return Optional.ofNullable(fetchFileVersion(fileId, version))
                .map(f -> f.toFileInfo())
                .orElseThrow(FileNotExist::new);
    }

    @Override
    public DownloadInfo fileVersionDownload(String fileId, int version) {
        return Optional.ofNullable(fetchFileVersion(fileId, version))
                .map(f -> DownloadInfo.builder()
                        .url(String.format("%s/console/download/%s/%d", host, f.getId().getId(), f.getId().getVersion()))
                        .build())
                .orElseThrow(FileVersionNotExist::new);
    }

    @Override
    public Watermark fileWatermark(String fileId) {
        return Watermark.builder()
                .type(Watermark.Type.TEXT)
                .value("Demo" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
                .fillStyle(Watermark.FillStyle.builder().alpha(0.6).red(192).green(192).blue(192).build())
                .rotate(-0.7853982)
                .horizontal(50)
                .vertical(100)
                .font("bold 20px Serif")
                .build();
    }
}
